#region Microsoft Public License
/*
 * (c) Copyright Chenjun Wu. http://utablesdk.codeplex.com
 * 
 * This source is subject to the Microsoft Public License (Ms-PL).
 * Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
 * All other rights reserved.
 */
#endregion

﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UTable.Objects.Controls;

namespace UTable.Objects
{
    /// <summary>
    /// It seems this class is just a set of invoke of UObjectTreeHost.cs
    /// </summary>
    public class ObjectControlTree: IVisualTree
    {

        #region Properties

        IObjectTree ObjectTree
        {
            get { return UObjectTreeHost.GetInstance(); }
        }
        #endregion

        #region Constructors

        private static ObjectControlTree _instance = new ObjectControlTree();

        private ObjectControlTree()
        {
        }

        public static ObjectControlTree GetInstance()
        {
            return _instance;
        }

        #endregion

        #region IVisualTree Members

        public IVisualNode TreeRoot
        {
            get
            {
                return ObjectTree.TreeRoot;
            }
            set
            {
                ObjectTree.SetRoot(value as IObject);
            }
        }

        public double TreeWidth
        {
            get { return ObjectTree.TreeWidth; }
        }

        public double TreeHeight
        {
            get { return ObjectTree.TreeHeight; }
        }

        public IVisualNode GetNodeByID(string id)
        {
            throw new NotImplementedException();
        }

        public IVisualNode GetParent(IVisualNode node)
        {
            if (node is IObject)
            {
                return ObjectTree.GetParent(node);
            }
            if (node is ControlInfo)
            {
                ControlInfo info = node as ControlInfo;
                if (info.Parent != null)
                    return info.Parent;
                else
                    return info.Entity;
            }
            return null;
        }

        public IVisualNode GetChild(IVisualNode node, int index)
        {
            if (GetChildrenCount(node) <= index)
                return null;
            if (node is ControlInfo)
            {
                return (node as ControlInfo).Children[index];
            }
            if (node is IObjectEntity)
            {
                if (index < (node as IObjectEntity).Children.Count)
                    return (node as IObjectEntity).Children[index];
                else
                    return (node as IObjectEntity).ControlTree.TreeRoot;
            }
            return null;
        }

        public int GetChildrenCount(IVisualNode node)
        {
            if (node is ControlInfo)
            {
                if ((node as ControlInfo).Children == null)
                    return 0;
                else
                    return (node as ControlInfo).Children.Count;
            }
            if (node is IObjectEntity)
            {
                return (node as IObjectEntity).Children.Count + 1;
            }
            return 0;
        }

        public HitTestResult HitTest(HitTestParameters hitTestParameters)
        {
            return (this.TreeRoot as IObjectEntity).HitTest(hitTestParameters);
        }

        public System.Windows.Point TranslatePoint(System.Windows.Point point, IVisualNode relativeTo)
        {
            if (relativeTo is IObjectEntity)
                return (this.TreeRoot as IObjectEntity).TranslatePoint(point, relativeTo);
            if (relativeTo is ControlInfo)
                return (relativeTo as ControlInfo).Entity.TranslatePoint((this.TreeRoot as IObject).TranslatePoint(point, (relativeTo as ControlInfo).Entity), relativeTo);
            return new System.Windows.Point(double.NaN, double.NaN);
        }

        public System.Windows.Point TranslatePoint(IVisualNode node, System.Windows.Point point, IVisualNode relativeTo)
        {
            if (node is IObjectEntity)
                return (node as IObjectEntity).TranslatePoint(point, relativeTo);
            if (node is ControlInfo)
            {
                return (node as ControlInfo).Entity.TranslatePoint(
                    (node as ControlInfo).TranslatePoint(point, (node as ControlInfo).Entity.ControlTree.TreeRoot),
                    relativeTo);
            }
            return new System.Windows.Point(double.NaN, double.NaN);
        }

        #endregion
    }
}
